#***********************************************************
#* Copyright (c) 2006, Zhimin Zhan.
#* Distributed open-source, see full license in MIT-LICENSE
#***********************************************************

require 'test/unit'

module RWebUnit

  class WebTestCase < Test::Unit::TestCase
    include RWebUnit::Utils

    attr_reader :web_tester

    def initialize(name=nil)
      super(name) if name
      @web_tester = WebTester.new
    end

    def default_test
      super unless(self.class == WebTestCase)
    end

    def text_context
      @web_tester.test_context
    end
    alias getTestContext text_context

    def begin_at(url)
      @web_tester.beginAt(url)
    end
    alias beginAt begin_at

    def open_browser(baseUrl, relativeUrl)
      getTestContext().base_url = baseUrl
      beginAt(relativeUrl)
    end
    alias openBrowser open_browser
    alias open_ie open_browser

    def close_browser
      @web_tester.closeBrowser
    end
    alias closeBrowser close_browser
    alias close_ie close_browser

    def go_back()
      @web_tester.goBack
    end
    alias goBack go_back

    def go_forward()
      @web_tester.goForward
    end
    alias goForward go_forward

    def goto_page(page)
      @web_tester.gotoPage(page)
    end
    alias gotoPage goto_page

    # assertions
    def assert_title_equals(title)
      @web_tester.assertTitleEquals(title)
    end
    alias assertTitleEquals assert_title_equals


    def assert_text_present(text)
      @web_tester.assertTextPresent(text)
    end
    alias assertTextPresent assert_text_present

    def assert_text_not_present(text)
      @web_tester.assertTextNotPresent(text)
    end
    alias assertTextNotPresent assert_text_not_present

    def assert_text_in_table(tableId, text)
      @web_tester.assertTextInTable(tableId, text)
    end
    alias assertTextInTable assert_text_in_table

    def assert_text_not_in_table(tableId, text)
      @web_tester.assertTextNotInTable(tableId, text)
    end
    alias assertTextNotInTable assert_text_not_in_table

    # textfields
    def set_form_element(elementName, elementValue)
      @web_tester.setFormElement(elementName, elementValue)
    end
    alias setFormElement set_form_element

    def assert_text_present_in_text_field(textfieldName, text, msg = nil)
      @web_tester.assertTextPresentInTextField(textfieldName, text, msg)
    end
    alias assertTextPresentInTextField assert_text_present_in_text_field

    #links
    def click_link_with_text(linkText)
      @web_tester.clickLinkWithText(linkText)
    end
    alias clickLinkWithText click_link_with_text

    def assert_link_present_with_text(linkText)
      @web_tester.assertLinkPresentWithText(linkText)
    end
    alias assertLinkPresentWithText assert_link_present_with_text

    def assert_link_not_present_with_text(linkText)
      @web_tester.assertLinkNotPresentWithText(linkText)
    end
    alias assertLinkNotPresentWithText assert_link_not_present_with_text

    ##
    # buttons

    # submit the form using the first (index) submit button
    def submit()
      @web_tester.submit()
    end

    def submit(buttonId)
      @web_tester.submit(buttonId)
    end

    def click_button(buttonId)
      @web_tester.clickButton(buttonId)
    end
    alias clickButton click_button

    def click_button_with_caption(caption)
      @web_tester.clickButtonWithCaption(caption)
    end
    alias clickButtonWithCaption click_button_with_caption
    alias click_button_with_text click_button_with_caption

    def click_button_with_value(value)
      @web_tester.clickButtonWithValue(value)
    end
    alias clickButtonWithValue click_button_with_value

    def assert_button_not_present(buttonID)
      @web_tester.assertButtonNotPresent(buttonID)
    end
    alias assertButtonNotPresent assert_button_not_present

    def assert_button_not_present_with_text(text)
      @web_tester.assertButtonNotPresentWithText(text)
    end
    alias assertButtonNotPresentWithText assert_button_not_present_with_text

    def assert_button_present(buttonID)
      @web_tester.assertButtonPresent(buttonID)
    end
    alias assertButtonPresent assert_button_present

    def assert_button_present_with_text(buttonID)
      @web_tester.assertButtonPresentWithText(buttonID)
    end
    alias assertButtonPresentWithText assert_button_present_with_text

    # checkbox
    def check_checkbox(checkBoxName)
      @web_tester.checkCheckbox(checkBoxName)
    end
    alias checkCheckbox check_checkbox

    def uncheck_checkbox(checkBoxName)
      @web_tester.uncheckCheckbox(checkBoxName)
    end
    alias uncheckCheckbox uncheck_checkbox

    def assert_checkbox_not_selected(checkBoxName)
      @web_tester.assertCheckboxNotSelected(checkBoxName)
    end
    alias assertCheckboxNotSelected assert_checkbox_not_selected

    def assert_checkbox_selected(checkBoxName)
      @web_tester.assertCheckboxSelected(checkBoxName)
    end
    alias assertCheckboxSelected assert_checkbox_selected

    # radio button
    def assert_radio_option_not_present(radioGroup, radioOption)
      @web_tester.assertRadioOptionNotPresent(radioGroup, radioOption)
    end
    alias assertRadioOptionNotPresent assert_radio_option_not_present

    def assert_radio_option_present(radioGroup, radioOption)
      @web_tester.assertRadioOptionPresent(radioGroup, radioOption)
    end
    alias assertRadioOptionPresent assert_radio_option_present

    def assert_radio_option_selected(radioGroup, radioOption)
      @web_tester.assertRadioOptionSelected(radioGroup, radioOption)
    end
    alias assertRadioOptionSelected assert_radio_option_selected

    def assert_radio_option_not_selected(radioGroup, radioOption)
      @web_tester.assertRadioOptionNotSelected(radioGroup, radioOption)
    end
    alias assertRadioOptionNotSelected assert_radio_option_not_selected

    # combo box
    def select_option(selectName, option)
      @web_tester.selectOption(selectName, option)
    end
    alias selectOption select_option

    # dhtml related
    def assert_element_present(elementID)
      @web_tester.assertElementPresent(elementID)
    end
    alias assertElementPresent assert_element_present

    def assert_element_not_present(elementID)
      @web_tester.assertElementNotPresent(elementID)
    end
    alias assertElementNotPresent assert_element_not_present

    # Wait for specific seconds for an Ajax update finish.
    # Trick: In your Rails application,
    #     :loading 	=> "Element.show('search_indicator');
    #     :complete	=> "Element.hide('search_indicator');
    #
    #   <%= image_tag("indicator.gif", :id => 'search_indicator', :style => 'display:none') %>
    #
    # In your test case:
    #    wait_ajax_update("search_indicator", "30)
    #
    # Warning: this method has not been fully tested, if you are not using Rails, change your parameter accordingly.
    #
    def ajax_wait_for_image(element_id, seconds, check_interval = 2)
      count = 0
      check_interval = 2 if check_interval < 1 or check_interval > seconds
      while count < (seconds / check_interval) do
        search_indicator = @web_tester.getElementById(element_id)
        search_indicator_outer_html = search_indicator.outerHtml if search_indicator
        return true if search_indicator_outer_html && search_indicator_outer_html.include?('style="DISPLAY: none"')
        sleep check_interval;
        count += 1
      end
      return false
    end
    alias wait_ajax_update ajax_wait_for_image

    def ajax_wait_for_element_show(element_id, seconds)
      raise 'not implemented'
    end

    def ajax_wait_for_element_hide(element_id, seconds)
      raise 'not implemented'
    end

    # for drag-n-drop, check the postion in list
    def assert_position_in_list(list_element_id)
      raise "not implemented"
    end

    # ---
    # For deubgging
    # ---
    def dump_response(stream = nil)
      @web_tester.dumpResponse(stream)
    end
    alias dumpResponse dump_response

  end

end
